'''
Created on Jan 10, 2010

@author: matan
'''

import math 

class BigramLidstone():
    '''
    Represents a bigram Lidstone smoothing model
    '''


    def __init__(self, uniCorpus, biCorpus):
        '''
        Constructor
        '''
        
        self.V = 300000
        self.corpus = uniCorpus    # corpus
        self.biCorpus = biCorpus
        self.lambdaParam = 0     # lambda parameter
#        self.denominator = float(self.corpus.S() + self.lambdaParam*self.); # optimization: used to calculated the denominator in the calculation of Lidstone smoothing
        
        
    def calcProbability(self, words):
        '''
        Calculates the probability of the given words according to Lidstone smoothing method
        '''
        c = self.biCorpus.C(words) 
        s = self.corpus.C(words[1])
        
        return (c + self.lambdaParam) / (s + self.lambdaParam * self.V)
    def setLambda(self, newLambda):
        self.lambdaParam = newLambda
        
    def calcPerplexity(self, condDic):
        '''
        Calculates the perplexity of the model according to the given test file
        '''
        
        perplexities = float(0)
        
        for w_cnd in condDic.keys():  
            
            sum = float(0)
            
            for w in condDic[w_cnd]:
                sum += math.log(self.calcProbability( (w, w_cnd) ), 2)
            
            perplexities += math.pow(2, -1.0 / len(condDic[w_cnd]) * sum)
            
        #return mean perplexity 
        return perplexities / len(condDic.keys())
        